*******************************************************************************
** Title: Analyzing the Rhetoric of Supreme Court Confirmation Hearings
** Author: Jake S. Truscott (University of Georgia) 
** Updated: December 2022
*******************************************************************************

import excel "<PATH TO SCOTUS_CH EXCEL FILE>", sheet("scotus_ch") firstrow


******************************************************************************
** Personalize Graph Output
*******************************************************************************
ssc install grstyle
grstyle clear
set scheme s2color
grstyle init
grstyle set plain, box
grstyle color background white
grstyle yesno draw_major_hgrid yes
grstyle yesno draw_major_ygrid yes
grstyle color major_grid gs6
grstyle linepattern major_grid dot
grstyle color ci_area gs12%50
graph set window fontface "Times New Roman"


*******************************************************************************
** Generate Necessary labels ** 
*******************************************************************************
gen committee_member_extremity = abs(speaker_nominate)

rename divided_unified divided_unified_written
gen divided_unified = 0 
replace divided_unified = 1 if divided_unified_written == "Divided"

rename gender gender_written 
gen gender = 0 
replace gender = 1 if gender_written == "Female"

rename nominee_gender nominee_gender_written
gen nominee_gender = 0
replace nominee_gender = 1 if nominee_gender_written == "Female"

gen post_bork = 0 
replace post_bork = 1 if hearing_id >= 7

gen televised_hearing = 0 
replace televised_hearing = 1 if year >= 1981

rename same_party same_party_written
gen same_party = 0 
replace same_party = 1 if same_party_written == "In Party"

gen naive_multi = 0 
replace naive_multi = 1 if naive_label >= 1
replace naive_multi = -1 if naive_label <=-1

label define divided 0 "Unified" 1 "Divided"
label define party 1 "In Party" 0 "Out Party"
label values same_party party
label values divided_unified divided
label define gender_label 0 "Male" 1 "Female"
label values gender gender_label
label values nominee_gender gender_label
label define naive_multi_label -1 "Negative" 0 "Neutral" 1 "Positive"
label values naive_multi naive_multi_label

label define hearing_short 1 "Rehnquist" 2 "Powell" 3 "Stevens" 4 "O'Connor" 5 "Rehnquist (CJ)" 6 "Scalia" 7 "Bork" 8 "Kennedy" 9 "Souter" 10 "Thomas I" 11 "Thomas II" 12 "Ginsburg" 13 "Breyer" 14 "Roberts" 15 "Alito" 16 "Sotomayor" 17 "Kagan" 18 "Gorsuch" 19 "Kavanaugh I" 20 "Kavanaugh II" 21 "Barrett"
label values hearing_id hearing_short

ssc install coefplot


*******************************************************************************
** Modelling 
** Multinomial Logit Based on Sentiment Label (+,-, or 0)
*******************************************************************************

*******************************************************************************
**Gen Cluster Term
*******************************************************************************
egen cluster_scotus = group(hearing_id speaker_hearing_id)

*******************************************************************************
**Main Model
*******************************************************************************
mlogit naive_multi i.post_bork i.televised_hearing i.divided_unified#i.same_party i.directed_at_nominee i.directed_at_committee i.election_year c.presidential_election c.nominate_distance c.committee_member_extremity c.president_approval i.law_degree i.public_dummy i.gender i.nominee_gender, cluster(cluster_scotus) base(0), if committee_member == 1


*******************************************************************************
**Key Events Model
*******************************************************************************
*Gen Key Events Terms*
gen bork = 0 
replace bork = 1 if hearing_id >= 7 & hearing_id < 10

gen thomas = 0 
replace thomas = 1 if hearing_id >= 10 & year <= 2016

gen garland = 0 
replace garland = 1 if year > 2016 & hearing_id < 19

gen kavanaugh = 0 
replace kavanaugh = 1 if hearing_id >= 19


*Standalone Model*
mlogit naive_multi i.bork i.thomas i.garland i.kavanaugh i.televised_hearing i.divided_unified#i.same_party i.directed_at_nominee i.directed_at_committee i.election_year c.presidential_election c.nominate_distance c.committee_member_extremity c.president_approval i.law_degree i.public_dummy i.gender i.nominee_gender, cluster(cluster_scotus) base(0), if committee_member == 1


********************************************************************************
********************************************************************************
*Article Figures*
********************************************************************************
********************************************************************************

********************************************************************************
*Figure 1* Average Rhetoric Sentiments by Hearing and Party Alignment
********************************************************************************

*Average Sentiment by Hearing*
bysort hearing_id: egen mean_sentiment =mean(naive_score) 
bysort hearing_id: egen median_sentiment =median(naive_score) 

* Average Sentiment by Hearing - by Party Alignments *
bysort hearing_id: egen mean_sentiment_same_party=mean(naive_score) if same_party == 1 
bysort hearing_id: egen median_sentiment_same_party=median(naive_score) if same_party == 1 

bysort hearing_id: egen mean_sentiment_opposite_party=mean(naive_score) if same_party == 0 
bysort hearing_id: egen median_sentiment_opposite_party=median(naive_score) if same_party == 0 


label define hearing_long 21 "Barrett" 20 "Kavanaugh II" 19 "Kavanaugh" 18 "Gorsuch" 17 "Kagan" 16 "Sotomayor" 15 "Alito" 14 "Roberts" 13 "Breyer" 12 "Ginsburg" 11 " Thomas II" 10 "Thomas" 9 "Souter" 8 "Kennedy" 7 "Bork" 6 "Scalia" 5 "Rehnquist (CJ)" 4 "O'Connor" 3 "Stevens" 2 "Powell"  1 "Rehnquist"

gen pos = 12
replace pos = 6 if same_party == 0 & hearing_id == 2 
replace pos = 6 if same_party == 0 & hearing_id == 17
replace pos = 6 if same_party == 0 & hearing_id == 15
replace pos = 3 if same_party == 0 & hearing_id == 18
replace pos = 5 if same_party == 0 & hearing_id == 9 
replace pos = 7 if same_party == 0 & hearing_id == 5
replace pos = 3 if same_party == 0 & hearing_id == 11
replace pos = 6 if same_party == 0 & hearing_id == 13
replace pos = 6 if same_party == 0 & hearing_id == 10
replace pos = 9 if same_party == 0 & hearing_id == 4
replace pos = 9 if same_party == 0 & hearing_id == 1 

replace pos = 6 if same_party == 1 & hearing_id == 19
replace pos = 3 if same_party == 1 & hearing_id == 18
replace pos = 6 if same_party == 1 & hearing_id == 12
replace pos = 6 if same_party == 1 & hearing_id == 6
replace pos = 2 if same_party == 1 & hearing_id == 21
replace pos = 6 if same_party == 1 & hearing_id == 17

duplicates drop hearing_id mean_sentiment_opposite_party mean_sentiment_same_party, force
*Note: Need to Re-Import Data After*

twoway (scatter mean_sentiment_same_party year, msize(vsmall) mlabel(hearing_id) mlabv(pos) mcolor(black) mlabsize(vsmall) mlabcolor(black) xsc(r(1970 2025))) (fpfit mean_sentiment_same_party year, lcolor(black) lpattern(shortdash) legend(off)  xsc(r(1970 2025))) (scatter mean_sentiment_opposite_party year, msize(vsmall) mlabel(hearing_id) mlabv(pos) msymbol(triangle) mcolor(gray) mlabsize(vsmall) mlabcolor(gray) xsc(r(1970 2025))) (fpfit mean_sentiment_opposite_party year, lcolor(gray) lpattern(shortdash) legend(off) xsc(r(1970 2025))), title("") xla(, notick) ylab(,nogrid) xlab(,nogrid) yline(0, lstyle(grid) lcolor(black%20) lpatter(shortdash)) by(same_party) 


********************************************************************************
*Figure 2* Effects of Hearings on Rhetorical Behaviors by Target
********************************************************************************
mlogit naive_multi i.bork i.thomas i.garland i.kavanaugh i.televised_hearing i.divided_unified#i.same_party i.directed_at_nominee i.directed_at_committee i.election_year c.presidential_election c.nominate_distance c.committee_member_extremity c.president_approval i.law_degree i.public_dummy i.gender i.nominee_gender, cluster(cluster_scotus) base(0), if committee_member == 1
quietly margins directed_at_nominee, predict(outcome(-1)) over(televised_hearing kavanaugh garland thomas bork) post
est store negative_nominee

mlogit naive_multi i.bork i.thomas i.garland i.kavanaugh i.televised_hearing i.divided_unified#i.same_party i.directed_at_nominee i.directed_at_committee i.election_year c.presidential_election c.nominate_distance c.committee_member_extremity c.president_approval i.law_degree i.public_dummy i.gender i.nominee_gender, cluster(cluster_scotus) base(0), if committee_member == 1
quietly margins directed_at_nominee, predict(outcome(1)) over(televised_hearing kavanaugh garland thomas bork) post
est store positive_nominee


coefplot positive_nominee negative_nominee


*********************************************************************************
*Figure 3* Predicted Rhetorical Behaviors of Committee Members by Divided or Unified Government
*********************************************************************************
mlogit naive_multi i.post_bork i.televised_hearing i.divided_unified#i.same_party i.directed_at_nominee i.directed_at_committee i.election_year c.presidential_election c.nominate_distance c.committee_member_extremity c.president_approval i.law_degree i.public_dummy i.gender i.nominee_gender, cluster(cluster_scotus) base(0), if committee_member == 1

quietly margins divided_unified#same_party, predict(outcome(-1)) post
est store pdu_negative_limited

mlogit naive_multi i.post_bork i.televised_hearing i.divided_unified#i.same_party i.directed_at_nominee i.directed_at_committee i.election_year c.presidential_election c.nominate_distance c.committee_member_extremity c.president_approval i.law_degree i.public_dummy i.gender i.nominee_gender, cluster(cluster_scotus) base(0), if committee_member == 1

quietly margins divided_unified#same_party, predict(outcome(1)) post

est store pdu_positive_limited

coefplot pdu_positive_limited pdu_negative_limited, name(limited_events)



mlogit naive_multi i.bork i.thomas i.garland i.kavanaugh i.televised_hearing i.divided_unified#i.same_party i.directed_at_nominee i.directed_at_committee i.election_year c.presidential_election c.nominate_distance c.committee_member_extremity c.president_approval i.law_degree i.public_dummy i.gender i.nominee_gender, cluster(cluster_scotus) base(0), if committee_member == 1

quietly margins divided_unified#same_party, predict(outcome(-1)) post
est store pdu_negative_additional

mlogit naive_multi i.bork i.thomas i.garland i.kavanaugh i.televised_hearing i.divided_unified#i.same_party i.directed_at_nominee i.directed_at_committee i.election_year c.presidential_election c.nominate_distance c.committee_member_extremity c.president_approval i.law_degree i.public_dummy i.gender i.nominee_gender, cluster(cluster_scotus) base(0), if committee_member == 1

quietly margins divided_unified#same_party, predict(outcome(1)) post

est store pdu_positive_additional

coefplot pdu_positive_additional pdu_negative_additional, name(additional_events)

coefplot pdu_positive_additional pdu_negative_additional, bylabel(Additional) || pdu_positive_limited pdu_negative_limited, bylabel(Limited) 


*********************************************************************************
*Figure 4* Party and Divided/Unified Independently
*********************************************************************************
mlogit naive_multi i.post_bork i.televised_hearing i.divided_unified#i.same_party i.directed_at_nominee i.directed_at_committee i.election_year c.presidential_election c.nominate_distance c.committee_member_extremity c.president_approval i.law_degree i.public_dummy i.gender i.nominee_gender, cluster(cluster_scotus) base(0), if committee_member == 1
quietly margins i.same_party,  predict(outcome(1))  predict(outcome(-1)) post
est store same_party_margins

mlogit naive_multi i.post_bork i.televised_hearing i.divided_unified#i.same_party i.directed_at_nominee i.directed_at_committee i.election_year c.presidential_election c.nominate_distance c.committee_member_extremity c.president_approval i.law_degree i.public_dummy i.gender i.nominee_gender, cluster(cluster_scotus) base(0), if committee_member == 1

quietly margins i.divided_unified,  predict(outcome(1)) predict(outcome(-1)) post
est store unified_margins

coefplot same_party_margins unified_margins



*********************************************************************************
*Check for Multicollinearity*
*********************************************************************************
net describe collin, from(https://stats.idre.ucla.edu/stat/stata/ado/analysis)
net install collin

gen divided_unified_same_party = divided_unified*same_party

*Table 3 w/out Interaction*
collin bork televised_hearing divided_unified same_party directed_at_nominee directed_at_committee election_year presidential_election nominate_distance committee_member_extremity president_approval law_degree public_dummy gender nominee_gender


*Table 3 w/ Interaction*
collin bork televised_hearing divided_unified same_party divided_unified_same_party directed_at_nominee directed_at_committee election_year presidential_election nominate_distance committee_member_extremity president_approval law_degree public_dummy gender nominee_gender

*********************************************************************************
**Appendix Models**
*********************************************************************************
*VIF w/out Interaction*
collin bork thomas garland kavanaugh televised_hearing divided_unified same_party directed_at_nominee directed_at_committee election_year presidential_election nominate_distance committee_member_extremity president_approval law_degree public_dummy gender nominee_gender

*VIF w/ Interaction*
collin bork thomas garland kavanaugh televised_hearing divided_unified same_party divided_unified_same_party directed_at_nominee directed_at_committee election_year presidential_election nominate_distance committee_member_extremity president_approval law_degree public_dummy gender nominee_gender

*********************************************************************************
*Figure A2* Predicted Rhetorical Behaviors of In-Party and Out-Party Members by Hearing
*********************************************************************************

mlogit naive_multi i.post_bork i.televised_hearing i.divided_unified#i.same_party  i.election_year c.presidential_election c.nominate_distance c.committee_member_extremity c.president_approval i.law_degree i.public_dummy i.gender i.nominee_gender, cluster(cluster_scotus) base(0), if committee_member == 1


quietly margins same_party, predict(outcome(-1)) over(hearing_id), if divided_unified == 0 & directed_at_nominee == 1, post
est store pdu_negative_unified 

mlogit naive_multi i.post_bork i.televised_hearing i.divided_unified#i.same_party i.election_year c.presidential_election c.nominate_distance c.committee_member_extremity c.president_approval i.law_degree i.public_dummy i.gender i.nominee_gender, cluster(cluster_scotus) base(0), if committee_member == 1

quietly margins same_party, predict(outcome(-1)) over(hearing_id), if divided_unified  == 1 & directed_at_nominee == 1, post
est store pdu_negative_divided


mlogit naive_multi i.post_bork i.televised_hearing i.divided_unified#i.same_party  i.election_year c.presidential_election c.nominate_distance c.committee_member_extremity c.president_approval i.law_degree i.public_dummy i.gender i.nominee_gender, cluster(cluster_scotus) base(0), if committee_member == 1

quietly margins same_party, predict(outcome(1)) over(hearing_id), if divided_unified == 0 & directed_at_nominee == 1, post
est store pdu_positive_unified
 
mlogit naive_multi i.post_bork i.televised_hearing i.divided_unified#i.same_party i.election_year c.presidential_election c.nominate_distance c.committee_member_extremity c.president_approval i.law_degree i.public_dummy i.gender i.nominee_gender, cluster(cluster_scotus) base(0), if committee_member == 1

quietly  margins same_party, predict(outcome(1)) over(hearing_id), if divided_unified == 1 & directed_at_nominee == 1, post
est store pdu_positive_divided

coefplot pdu_positive_divided pdu_negative_divided,  name(divided, replace)

coefplot pdu_positive_unified pdu_negative_unified, name(unified, replace)

gr combine divided unified



